package com.example.baselib.widget;

import com.example.baselib.utils.log.LogLevel;
import com.example.baselib.utils.log.LogManager;
import com.example.baselib.utils.log.LogUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ScrollHelper;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.multimodalinput.event.TouchEvent;

public class RefreshLayout extends ComponentContainer implements Component.TouchEventListener, Component.LayoutRefreshedListener {

    private IRComponent.RCState mRCState;
    //刷新组件
    private IRComponent irComponent;
    private float mLastFocusX;
    private float mLastFocusY;
    private RecoverScrollHelper scrollHelper;

    public RefreshLayout(Context context) {
        this(context, null);
    }

    public RefreshLayout(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public RefreshLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        scrollHelper = new RecoverScrollHelper();
        //添加触摸监听
        setTouchEventListener(this);
        setLayoutRefreshedListener(this);
    }


    @Override
    public void onRefreshed(Component component) {
        //获取下拉刷新组件
        Component head = getComponentAt(0);
        if (head instanceof IRComponent) {
            irComponent = ((IRComponent) head);
            mRCState = ((IRComponent) head).getRCState();
            if (mRCState == IRComponent.RCState.STATE_INIT) {
                LayoutConfig config = new LayoutConfig();
                config.width = LayoutConfig.MATCH_PARENT;
                config.height = LayoutConfig.MATCH_CONTENT;

                int height = head.getHeight();
                head.setComponentPosition(0, -100, 0, 0);
                head.setLayoutConfig(config);

                ((IRComponent) head).init(config);
                ((IRComponent) head).setRCState(IRComponent.RCState.STATE_PREPARE);
                LogUtils.i("初始化 刷新组件" + height);
            }
        }
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        Component hard = getComponentAt(0);
        int action = touchEvent.getAction();

        float sumY = 0.0f;
        float sumX = 0.0f;

        //是否有手指抬起来
        final boolean pointerUp = action == TouchEvent.OTHER_POINT_UP;
        //获取手指抬起的索引
        final int upIndex = pointerUp ? touchEvent.getIndex() : -1;
        //获取触摸总数
        int pc = touchEvent.getPointerCount();
        for (int i = 0; i < pc; i++) {
            if (upIndex == i) {
                continue;
            }
            sumX += touchEvent.getPointerPosition(i).getX();
            sumY += touchEvent.getPointerPosition(i).getY();
        }
        //获取实际的触摸数量
        final int nPC = pointerUp ? pc - 1 : pc;
        //获取多个触摸的平均焦点坐标
        final float currFocusX = sumX / nPC;
        final float currFocusY = sumY / nPC;

        LogUtils.i("当前坐标和 X: %s Y:%s", sumX, sumY);
        LogUtils.i("平均坐标   X: %s Y:%s", currFocusX, currFocusY);
        LogManager.getInstance().setLogLevel(LogLevel.DEBUG);
        LogUtils.i("onTouchEvent %d", action);

        switch (action) {
            case TouchEvent.OTHER_POINT_DOWN: //触摸过程中有手指落下
            case TouchEvent.OTHER_POINT_UP:   //触摸过程中有手指抬起
            case TouchEvent.PRIMARY_POINT_DOWN: //首次触摸落下
                mLastFocusX = currFocusX;
                mLastFocusY = currFocusY;
                break;
            case TouchEvent.POINT_MOVE: //滑动
                float scrollX = currFocusX - mLastFocusX;
                float scrollY = currFocusY - mLastFocusY;
                if (isVerticalMove(currFocusX, currFocusY)) {
                    int offsetY;
                    int dispHeight = getDisplayHeight(hard);
                    if (dispHeight < irComponent.getMinLoadHeight()) {
                        offsetY = (int) (scrollY / 1.2f);
                    } else {
                        offsetY = (int) (scrollY / 2.4f);
                    }
                    boolean isScroll = scrollComponent(offsetY);
                    this.mLastFocusX = currFocusX;
                    this.mLastFocusY = currFocusY;
                    return isScroll;
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP: //抬起
                recoverComponent();
                break;
            case TouchEvent.CANCEL: //取消
                break;
        }
        return false;
    }

    private void recoverComponent() {
        Component head = getComponentAt(0);
        Component content = getComponentAt(1);
        if (head.getBottom() > irComponent.getMinLoadHeight()) {
            int dis = head.getBottom() - irComponent.getMinLoadHeight();
            scrollHelper.recoverComponent(dis);
        }
    }


    //模拟滚动
    protected boolean scrollComponent(int offsetY) {
        LogUtils.d("offsetY ------>%s", offsetY);
        Component component = getComponentAt(0);
        Component content = getComponentAt(1);

        offsetTopAndBottom(component, offsetY);
        offsetTopAndBottom(content, offsetY);
        return true;
    }


    /**
     * 是否为垂直滑动
     *
     * @return true 表示 垂直移动
     */
    private boolean isVerticalMove(float x, float y) {
        return Math.abs(y - mLastFocusY) > Math.abs(x - mLastFocusX);
    }

    /**
     * 获取控件显示高度(可见高度)
     */
    private int getDisplayHeight(Component component) {
        return component.getTop();
    }

    private void offsetTopAndBottom(Component component, int offset) {
        component.setTop(component.getTop() + offset);
        component.setBottom(component.getBottom() + offset);
        component.setComponentPosition(component.getLeft(), component.getTop(), component.getRight(), component.getBottom());
    }


    class RecoverScrollHelper implements Runnable {

        private EventHandler handler;
        private ScrollHelper scrollHelper;
        private boolean mIsFinish;
        private int mLastY;

        public RecoverScrollHelper() {
            handler = new EventHandler(EventRunner.getMainEventRunner());
            scrollHelper = new ScrollHelper();
        }

        @Override
        public void run() {
            if (!scrollHelper.isFinished()) {
                scrollHelper.updateScroll();
                scrollComponent(mLastY - scrollHelper.getCurrValue(ScrollHelper.AXIS_Y));
                mLastY = scrollHelper.getCurrValue(ScrollHelper.AXIS_Y);
                handler.postTask(this);
            } else {
                handler.removeTask(this);
                mIsFinish = true;
            }

        }

        public void recoverComponent(int dis) {
            handler.removeTask(this);
            mIsFinish = false;
            scrollHelper.startScroll(0, 0, 0, dis);
            handler.postTask(this);
        }

        boolean isFinish() {
            return mIsFinish;
        }
    }


}
